﻿using Beryl.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Timers;


namespace Beryl
{
    public class CommonMethod
    {

        private static CommonMethod instance = null;
        private static readonly object uniqueLock = new object();
        public static Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> VaildBom = null;
        public static DataRow[] APS_ManuBOM = null;
        public static DataRow[] APS_Routing = null;
        public static CommonMethod Instance
        {
            get
            {
                lock (uniqueLock)
                {
                    if (instance == null)
                    {
                        instance = new CommonMethod();
                    }
                }
                return instance;
            }
        }
        public CommonMethod() { }


        //返回刀具信息：0 成功 1 预警 2 报废
        public string checkKn(string stand,string Long,string dCumulativeMeter)
        {
            double DQ = double.Parse(dCumulativeMeter) + double.Parse(Long);
            double result = double.Parse(stand) - DQ;
            if(result < 0)
            {
                return "[2]";
            }else if(result > 0 && result < 100)
            {
                return "[1]";
            }else
            {
                return "[0]";
            }
            
        }

        //更新刀具状态
        public string KnStatus(string Kn,string Long)
        {
            string sql = string.Format(@"select * from PMS_BladeGroup where cBladeGroupNum = '{0}'", Kn);
            var k = selectDatabase(sql);
            var KnRow = k.Select($"cBladeGroupNum = '{Kn}'");
            var Kn1 = KnRow[0];
            string dStandardMeter = Kn1["dStandardMeter"].ToString();
            string dCumulativeMeter = Kn1["dCumulativeMeter"].ToString();
            double DQ = double.Parse(dCumulativeMeter) + double.Parse(Long);
            double T = double.Parse(dStandardMeter) * 0.95;
            if(T > DQ)
            {
                return DQ.ToString();
            }
            return "报废";
        }

        //查询通用方法
        public  DataTable selectDatabase(string para)
        {
            //Console.WriteLine(sql);
            SqlHelper.IniConnString();
            var connstr = SqlHelper.GetConnSting();
            DataTable dt = SqlHelper.ExecuteDataset(connstr, CommandType.Text, para).Tables[0];
            return dt;
        }

        //设置开工记录时间数据
        public string CheckPRData(string para)
        {
            string json;
            try
            {
                Newtonsoft.Json.Linq.JArray jsonArr = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(para);
                var k = jsonArr[0];
                DateTime currentTime = DateTime.Now;
                DateTime startTime = DateTime.Parse(k["cProStartTime"].ToString());
                int sHour = startTime.Hour;
                int sMinute = startTime.Minute;
                string hhs = sHour.ToString();
                string mms = sMinute.ToString();
                if (sHour < 10)
                {
                    hhs = "0" + sHour.ToString();
                }
                if (sMinute < 10)
                {
                    mms = "0" + sMinute.ToString();
                }
                string SHM = hhs + ":" + mms;
                long currentTime1 = GetIntFromTime(currentTime);
                long startTime1 = GetIntFromTime(startTime);
                if (currentTime1 - startTime1 <= 60000)
                {
                    currentTime = currentTime.AddMinutes(1);
                }
                int myHour = currentTime.Hour;
                int myMinute = currentTime.Minute;
                string hh = myHour.ToString();
                string mm =myMinute.ToString();
                if (myHour < 10)
                {
                     hh = "0" + myHour.ToString();
                }
                if (myMinute < 10)
                {
                     mm = "0" + myMinute.ToString();
                }
                string endTime = hh + ":" + mm;

                DateTime dd = Convert.ToDateTime("00:00");
                DateTime dd1 = Convert.ToDateTime("08:00");
                DateTime ddd = Convert.ToDateTime("20:00");
                DateTime ddd1 = Convert.ToDateTime("23:59");
                DateTime dddd = Convert.ToDateTime("08:00");
                DateTime dddd1 = Convert.ToDateTime("20:00");
                string bc = "";
                DateTime endTime1 = Convert.ToDateTime(endTime);
                if ((DateTime.Compare(endTime1, dd) > 0 && DateTime.Compare(endTime1, dd1) < 0) || (DateTime.Compare(endTime1, ddd) > 0 && DateTime.Compare(endTime1, ddd1) < 0))//夜班  
                {
                    bc = "1";
                }
                if (DateTime.Compare(endTime1, dddd) > 0 && DateTime.Compare(endTime1, dddd1) < 0)//白班
                {
                    bc = "0";
                }
                Dictionary<string, string> map = JsonConvert.DeserializeObject<Dictionary<string, string>>(k.ToString());
                map.Add("startDay", k["cProStartTime"].ToString().Split(' ')[0]);
                map.Add("startHM", SHM);
                map.Add("endTime", endTime);
                map.Add("Bc", bc);
                json= JsonConvert.SerializeObject(map);
                json = JosnChange(json);
            }
            catch(Exception e)
            {
                json = e.Message;
            }
            return json;
        }

        //获取来料数
        public string getLLNum(string para,string cMOLotNo,string gx,string lastGx,string dLotQty)
        {
            double Numberbox3 = 0.00;
            string upGX = "";
            double preGNumber = 0.00;
            double done = 0;
            try
            {
                string sql = string.Format(@"select cMOLotNo,sum(GNumber+ANumber) as Total from APS_PhistoryTable where cMOLotNo = '{0}' and cProcess = '{1}' and isReturnReport = '0' group by cMOLotNo", cMOLotNo, para);
                var k1 = selectDatabase(sql);
                var KnRow = k1.Select($"cMOLotNo = '{cMOLotNo}'");
                var Kn1 = KnRow[0];
                
                if (Kn1["Total"].ToString() != "")
                {
                    done = double.Parse(Kn1["Total"].ToString());
                }
                Newtonsoft.Json.Linq.JArray GX = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(gx);
                Newtonsoft.Json.Linq.JArray lastGX = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(lastGx);
                string DJ = GX[0]["cOperationName"].ToString();
                if (para.Contains(DJ))//如果当前工序为钉卷
                {
                    Numberbox3 = double.Parse(dLotQty) - done;
                }else
                {
                    for (int i = 0; i < lastGX.Count; i++)
                    {
                        if (para.Contains(lastGX[i]["cOperationName"].ToString()))
                        {
                            upGX = lastGX[i + 1]["cOperationName"].ToString();
                            string downGX = lastGX[i + 1]["cOperationNo"].ToString();
                            break;
                        }
                    }
                    preGNumber = double.Parse(dLotQty);
                    string sql2 = string.Format(@"select b.cMOLotNo,b.GNumber,b.Total,a.cOpSeq,a.cOperationNo,a.cOperationName,a.cMatNo from APS_ValidRouting a inner join 
(select cMOLotNo,sum(GNumber) as GNumber,sum(GNumber+ANumber) as Total,cProcessCode from APS_PhistoryTable where cMOLotNo = '{0}' and isReturnReport = '0' and cProEndTime is not null group by cMOLotNo,cProcessCode) b
on a.cOrderNo = b.cMOLotNo and a.cOperationNo = b.cProcessCode
order by a.cOpSeq desc", cMOLotNo);
                    var kGX = selectDatabase(sql2);
                    var knGXValue = kGX.Select($"cMOLotNo = '{cMOLotNo}'");
                    for (int j = 0; j < knGXValue.Count(); j++)
                    {
                        if (upGX.Contains(knGXValue[j]["cOperationName"].ToString()))
                        {
                            preGNumber = double.Parse(knGXValue[j]["GNumber"].ToString());
                            break;
                        }
                    }
                    Numberbox3 = preGNumber - done;
                }
            }
            catch(Exception e)
            {
                return "error" + e.Message;
            }
            return Numberbox3.ToString();
        }



        //不能超过首工序10% 未修改

        //检查开工记录提交数据
        public string CheckPRSummitData(string para)
        {
            double topNum = 0.00;
            int totalNum = 0;
            bool preReportFlag = false;
            string json;
            try
            {
                Newtonsoft.Json.Linq.JArray jsonArr = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(para);
                var k = jsonArr[0];
                DateTime startDay = DateTime.Parse(k["开始日期"].ToString());
                DateTime EndDay = DateTime.Parse(k["结束日期"].ToString());
                DateTime startTime = DateTime.Parse(k["开始时间"].ToString());
                DateTime EndTime = DateTime.Parse(k["结束时间"].ToString());
                if (DateTime.Compare(startDay, EndDay) > 0)
                {
                    return "开始日期大于结束日期";
                }
                if (DateTime.Compare(startDay, EndDay) == 0 && DateTime.Compare(startTime, EndTime) >= 0)
                {
                    return "开始时间大于结束时间";
                }
                if ((DateTime.Compare(startDay, EndDay) < 0) || (DateTime.Compare(startDay, EndDay) == 0 && DateTime.Compare(startTime, EndTime) <= 0))
                {
                    string cMOLotNo = k["生产批次号"].ToString();
                    string GNumber = k["良品数"].ToString();
                    string ANumber = k["不良数"].ToString();
                    totalNum = int.Parse(GNumber) + int.Parse(ANumber);
                    double dLotQty = double.Parse(k["订单数量"].ToString());
                    string cProductDepNo = k["部门编码"].ToString().Substring(1);
                    string currentGXName = k["当前工序"].ToString();
                    string currentGXNo = k["当前工序No"].ToString();
                    //查询当前工序已报工数量
                    string sql = string.Format(@"select cMOLotNo,sum(GNumber+ANumber) as Total from APS_PhistoryTable where cMOLotNo = '{0}' and cProcess = '{1}' and isReturnReport = '0' group by cMOLotNo", cMOLotNo, currentGXName);
                    var k1 = selectDatabase(sql);
                    var KnRow = k1.Select($"cMOLotNo = '{cMOLotNo}'");
                    var Kn1 = KnRow[0];
                    double done = 0;
                    if (Kn1["Total"].ToString() != "")
                    {
                        done = double.Parse(Kn1["Total"].ToString());
                    }
                    //查询当前工序（钉卷）报工百分比
                    string sql1 = string.Format(@"select * from PMS_ProcessPara where cProgramCode = '{0}' and cProcessCode = '{1}'", cProductDepNo, currentGXNo);
                    var kValue = selectDatabase(sql1);
                    var knValue = kValue.Select($"cProcessCode = '{currentGXNo}'");
                    if (knValue.Length > 0)
                    {
                        var knValue1 = knValue[0];
                        int reportPercent = int.Parse(knValue1["cValue"].ToString());
                        topNum = dLotQty;
                        double preGNumber = dLotQty; //上工序合格数
                        Newtonsoft.Json.Linq.JArray GX = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(k["工序"].ToString());
                      
                        
                        string DJ = GX[0]["cOperationName"].ToString();
                        string upGX = "";
                        string downGX = "";

                        if (currentGXName.Contains(DJ))//如果当前工序为钉卷
                        {
                            topNum = Math.Ceiling(dLotQty * (1 + reportPercent) * 0.01) - done;
                            preReportFlag = true;
                        }
                        else
                        {
                            Newtonsoft.Json.Linq.JArray lastGX = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(k["最后工序"].ToString());
                            for (int i = 0; i < lastGX.Count; i++)
                            {
                                if (currentGXName.Contains(lastGX[i]["cOperationName"].ToString()))
                                {
                                    upGX = lastGX[i + 1]["cOperationName"].ToString();
                                    downGX = lastGX[i + 1]["cOperationNo"].ToString();
                                    break;
                                }
                            }
                            //其他工序报工数量根据（上工序合格数的百分比）来控制
                            //按工艺路径顺序查找上工序
                            string sql2 = string.Format(@"select b.cMOLotNo,b.GNumber,b.Total,a.cOpSeq,a.cOperationNo,a.cOperationName,a.cMatNo from APS_ValidRouting a inner join 
(select cMOLotNo,sum(GNumber) as GNumber,sum(GNumber+ANumber) as Total,cProcessCode from APS_PhistoryTable where cMOLotNo = '{0}' and isReturnReport = '0' and cProEndTime is not null group by cMOLotNo,cProcessCode) b
on a.cOrderNo = b.cMOLotNo and a.cOperationNo = b.cProcessCode
order by a.cOpSeq desc", cMOLotNo);
                            var kGX = selectDatabase(sql2);
                            var knGXValue = kGX.Select($"cMOLotNo = '{cMOLotNo}'");
                            for (int j = 0; j < knGXValue.Count(); j++)
                            {
                                if (upGX.Contains(knGXValue[j]["cOperationName"].ToString()))
                                {
                                    preGNumber = double.Parse(knGXValue[j]["GNumber"].ToString());
                                    preReportFlag = true;
                                    break;
                                }
                            }
                            topNum = Math.Ceiling(preGNumber * (1 + reportPercent * 0.01)) - done;
                        }
                    }
                }
                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic.Add("上工序标识", preReportFlag.ToString());
                dic.Add("上工序数", topNum.ToString());
                dic.Add("本工序数", totalNum.ToString());
                json = JsonConvert.SerializeObject(dic);
                json = JosnChange(json);
            }
            catch(Exception e)
            {
                return e.Message;
            }
            return json;
        }



        private long lLeft = 621355968000000000;

        //将时间变成数字
        public long GetIntFromTime(DateTime dt)
        {
            DateTime dt1 = dt.ToUniversalTime();
            //long Sticks = (dt1.Ticks - lLeft) / 10000000;
            long Sticks = (dt1.Ticks - lLeft) / 10000;
            return Sticks;

        }

        //将数字变成时间
        public string GetTimeFromInt(long ltime)
        {

           // long Eticks = (long)(ltime * 10000000) + lLeft;
            long Eticks = (long)(ltime * 10000) + lLeft;
            DateTime dt = new DateTime(Eticks).ToLocalTime();
            return dt.ToString();

        }


        /**
     * json格式转换20230810
     * @param json
     * @return
     */
        public string JosnChange(string json)
        {
            string result = "";
            if (json.Substring(0, 1).Equals("["))
            {
                json = json.Replace("[", "");
                json = json.Replace("]", "");
                result = json;
                return result;
            }
            if (json.Substring(0, 1).Equals("{"))
            {
                json = "[" + json + "]";
                result = json;
            }
            return result;
        }

        //获取时间
        public string getTimes()
        {
            DateTime dt = DateTime.Now;
            string date = dt.ToString("yyyy-MM-dd HH:mm:ss");
            return date;
        }

        public string getTimes1()
        {
            DateTime dt = DateTime.Now;
            string date = dt.ToString("yyyy/MM/dd HH:mm:ss");
            return date;
        }

        public string getTimes2()
        {
            DateTime dt = DateTime.Now;
            string date = dt.ToString("yyMMdd");
            return date;
        }

        public string getTime3()
        {
            DateTime dt = DateTime.Now;
            string date = dt.ToString("yyyy-MM-dd");
            return date;
        }

        //开始时间不能大于结束时间
        //参数1 为开始时间，2为结束时间
        public bool DataLineOut(string cProStartTime, string cProEndTime)
        {
            long sMin = CommonMethod.Instance.GetIntFromTime(DateTime.Parse(cProStartTime));
            long eMIn = CommonMethod.Instance.GetIntFromTime(DateTime.Parse(cProEndTime));

            if (sMin > eMIn)//开始时间不能大于结束时间
            {
                return false;
            }
            return true;
        }


        //结束时间不能大于开始时间10分钟
        public bool timeInterval(string cProStartTime, string cProEndTime)
        {
            long sMin = CommonMethod.Instance.GetIntFromTime(DateTime.Parse(cProStartTime));
            long eMIn = CommonMethod.Instance.GetIntFromTime(DateTime.Parse(cProEndTime));
            if (sMin > eMIn)//开始时间不能大于结束时间
            {
                return false;
            }

            if (eMIn - sMin <= 600000)//开始时间与结束时间少于10分钟
            {
                return false;
            }
            return true;
        }

        //日志写入
        public void InsertLog(string Method,string data, LogType logType,string phoneData,string message)
        {
           
                string sql;
                string date = getTimes();

                if (phoneData != "")
                {
                    Newtonsoft.Json.Linq.JArray jsonArr = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(phoneData);
                    string account = jsonArr[0]["账号"].ToString();
                    string mac = jsonArr[0]["MAC"].ToString();
                    sql = string.Format(@"insert into Android_Log (Result,MAC,Method,Time,account,message,Type) values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}');", data, mac, Method, date, account,message, logType.ToString());
                }
                else
                {
                    sql = string.Format(@"insert into Android_Log (Result,MAC,Method,Time,account,message,Type) values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}');", data, "null", Method, date, "null",message,logType.ToString());
                }
                var connstr = SqlHelper.GetConnSting();
                SqlHelper.ExecuteNonQuery(connstr, CommandType.Text, sql);
        }

        public void InsertLog1(string barCode,string data,string phoneData, LogType logType, string Method,string UserName,bool PAD)
        {
            string sql;
            string date = getTimes();
            if (phoneData != "")
            {
                Newtonsoft.Json.Linq.JArray jsonArr = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(phoneData);
                string account = jsonArr[0]["账号"].ToString();
                string mac = jsonArr[0]["MAC"].ToString();
                sql = string.Format(@"insert into WebService_Log (Barcode,Message,MAC,Method,Time,account,UserName,Type,PDA) values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}');", barCode, data, mac, Method, date, account, UserName, logType.ToString(),PAD);
            }else
            {
                sql = string.Format(@"insert into WebService_Log (Barcode,Message,MAC,Method,Time,account,UserName,Type,PDA) values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}');", barCode, data, "", Method, date, "", UserName, logType.ToString(), PAD);
            }
            var connstr = SqlHelper.GetConnSting();
            SqlHelper.ExecuteNonQuery(connstr, CommandType.Text, sql);
        }

        public enum LogType
        {
            Debug,

            Info,

            Error
        }

        public Newtonsoft.Json.Linq.JArray  jsonToJsonArray(string json)
        {
            Newtonsoft.Json.Linq.JArray jsonArr;
            try
            {
                jsonArr  = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(json);

            }catch(Exception e)
            {
                return null;
            }
            return jsonArr;
        }

        //DataGridView 分页数据返回
        public DataTable GetData(int pageIndex, int pageSize, string sql, out int total)
        {
            DataTable dt = new DataTable();
            DataSet ds = new DataSet();
            var connstr = SqlHelper.GetConnSting();
            using (SqlConnection conn = new SqlConnection(connstr))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand())
                {
                    cmd.Connection = conn;
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "p_splitpage";
                    SqlParameter pa_sql = new SqlParameter("@sql", sql);
                    SqlParameter pa_page = new SqlParameter("@page", pageIndex);
                    SqlParameter pa_pageSize = new SqlParameter("@pageSize", pageSize);
                    SqlParameter pa_pageCount = new SqlParameter();
                    {
                        pa_pageCount.ParameterName = "@pageCount";
                        pa_pageCount.Direction = ParameterDirection.InputOutput;
                        pa_pageCount.DbType = DbType.Int32;
                        pa_pageCount.Value = 0;
                    }

                    SqlParameter pa_recordCount = new SqlParameter();
                    {
                        pa_recordCount.ParameterName = "@recordCount";
                        pa_recordCount.Direction = ParameterDirection.InputOutput;
                        pa_recordCount.DbType = DbType.Int32;
                        pa_recordCount.Value = 0;
                    }

                    SqlParameter pa_searchTime = new SqlParameter();
                    {
                        pa_searchTime.ParameterName = "@SearchTime";
                        pa_searchTime.Direction = ParameterDirection.InputOutput;
                        pa_searchTime.DbType = DbType.Int32;
                        pa_searchTime.Value = 0;
                    }

                    cmd.Parameters.Add(pa_sql);
                    cmd.Parameters.Add(pa_page);
                    cmd.Parameters.Add(pa_pageSize);
                    cmd.Parameters.Add(pa_pageCount);
                    cmd.Parameters.Add(pa_recordCount);
                    cmd.Parameters.Add(pa_searchTime);
                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);

                    adapter.Fill(ds);
                    dt = ds.Tables[1];
                    total = Convert.ToInt32(pa_recordCount.Value);

                }
                conn.Close();
            }
            return ds.Tables[1];
        }

        // para 结束时间, para1 开始时间
        public int diffDate(string para, string para1)
        {
            string date = para.Replace("/", "-");
            string date1 = para1.Replace("/", "-");
            long s1 = Instance.GetIntFromTime(DateTime.Parse(date));
            long s2 = Instance.GetIntFromTime(DateTime.Parse(date1));
            long days = s1 - s2;
            int time = (int)days / (1000 * 60 * 60 * 24);
            return time;
        }

        //json添加元素
        public string JsonAddItem(string json,string newJson)
        {
            if(!json.StartsWith("["))
            {
                json = JosnChange(json);
            }
            newJson = JosnChange(newJson);

            Newtonsoft.Json.Linq.JArray jArray = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(json);

            Newtonsoft.Json.Linq.JArray jArray1 = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(newJson);
            jArray.Add(jArray1[0]);

            //JObject jsonObject = JObject.Parse(json);
            //JArray jsonArray = new JArray(jsonObject);
            //JObject NewJsonObject = JObject.Parse(newJson);
            //jsonArray.Add(NewJsonObject);
            string jsonArrayString = jArray.ToString();
            return jsonArrayString;
        }

        //查询结果返回
        public DataRow[] retData(string sql,string para,string para1)
        {
            DataRow[] SorderLimitRow = null;
            try
            {
                var SorderLimitSelect = selectDatabase(sql);
                if(para == "")
                {
                    SorderLimitRow = SorderLimitSelect.Select("1 = 1");
                }else
                {
                    SorderLimitRow = SorderLimitSelect.Select(para + "= '" + para1 + "'");
                }
            }
            catch(Exception)
            {
                return SorderLimitRow;
            }
            return SorderLimitRow;
        }

        //组合cReworkNo
        public string sumcReworkNO(int count, string para, string cReworkNo)
        {
            if (count > 1)
            {
                int len = para.Split('-').Length;
                if (len == 3)
                {
                    int num = int.Parse(para.Split('-')[2]);
                    num = num + 1;
                    cReworkNo = cReworkNo + "-" + num;
                }
                else
                {
                    var len1 = para.Split('-').Length;
                    var num1 = int.Parse(para.Split('-')[len1 - 1]);
                    num1 = num1 + 1;
                    cReworkNo = cReworkNo + "-" + num1;
                }
            }
            if (count == 1)
            {
                if (para.Split('-').Length == 3)
                {
                    int num = int.Parse(para.Split('-')[2]);
                    num = num + 1;
                    cReworkNo = cReworkNo + "-" + num;
                }
                else
                {
                    cReworkNo = cReworkNo + "-" + "1";
                }
            }
            if (count == 0)
            {
                cReworkNo = (count > 0) ? (cReworkNo + "-" + count) : cReworkNo;
            }
            return cReworkNo;
        }

        #region 计数器执行
        //获取APS_ValidBOM 公共方法
        public static void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                instance.QueryData();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"定时任务触发失败：{ex.Message}");
            }
        }


        //获取APS_ManuBOM & APS_Routing
        public static void Timer_global(object sender, ElapsedEventArgs e)
        {
            try
            {
                instance.GetGlobal();
            }
            catch(Exception ex)
            {
                Console.WriteLine($"定时任务触发失败：{ex.Message}");
            }
        }


        //判断计数器是否执行
        public void Timer_Start()
        {
            if(TimerServer.timer == null || VaildBom == null)
            {
                TimerServer.Instance.StartTask();
                //Thread.Sleep(12000);
            }
        }

        public void Global_Start()
        {
            if(TimerServer.global == null || APS_ManuBOM == null || APS_Routing == null)
            {
                TimerServer.Instance.StartTask1();
            }
        }

        public void QueryData()
        {
            try
            {
                string APS_Valid = string.Format(@"SELECT cOrderNo,cMatNo,dPlanQty,cOperationNo,cOperationName,cOpSeq,cMatandResNo,cMatandResName,cMatandResType," +
                              "dWidth,dLength,cSpecifution,cUnit,dReqQty,cCapacityLow,cCapacityUp,cCapacity,cBomid,cCateNo,dVoltage,Unit,cSortSeq  FROM APS_ValidBOM");
                var ValidRow = Instance.retData(APS_Valid, "", "");
                if (ValidRow != null)
                {
                    VaildBom =  getValidBOM(ValidRow);
                }
            }
            catch (Exception ex)
            {
                return;
            }
        }


        public void GetGlobal()
        {
            try
            {
                // 物料BOM
                string ManuBOM = string.Format(@"SELECT
                            cMatNo,
                            cOperationNo,
                            cInOutType,
                            cMatandResNo,
                            cMatandResName,
                            cMatandResType,
                            dQty,
                            dMeasureUnit,
                            cSpecifucation,
                            CompScrap,
                            cCapacityLow,
                            cCapacityup,
                            cCapacity,
                            cBomid,
                            SortSeq
                        FROM
                            APS_ManuBOM_V
                        WHERE
                            cMatNo IS NOT NULL
                        ORDER BY cOperationNo DESC");
                var APS_ManuBOMRow = retData(ManuBOM, "", "");

                string Routing = string.Format(@"SELECT
                            bd.cMatNo,
                            bd.cProgramCode1 as cPRoutingId,
                            bd.cCombination,
                            bd.cProcessSerialNum as cOpSeq,
                            bd.cProcessCode1 as cOperationNo,
                            bd.cProcessName as cOperationName,
                            bd.dTransferTime
                        FROM
                            APS_BaseData_V bd
                        WHERE
                            bd.cMatNo LIKE 'C%'
                        ORDER BY
                            bd.cMatNo,
                            bd.cProcessSerialNum");
                var APS_RoutingRow = retData(Routing, "", "");
                if(APS_ManuBOMRow == null || APS_RoutingRow == null)
                {
                    throw new Exception("查询失败");
                }
                APS_ManuBOM = APS_ManuBOMRow;
                APS_Routing = APS_RoutingRow;
            }
            catch(Exception e)
            {
                return;
            }
        }

        //生产订单ValidBom结构化
        public Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> getValidBOM(DataRow[] dataRows)
        {
            Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> VaildBomObj = new Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>>();
            Dictionary<string, Dictionary<string, Dictionary<string, string>>> valuePairs = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
            Dictionary<string, Dictionary<string, string>> keyValuePairs = new Dictionary<string, Dictionary<string, string>>();
            Dictionary<string, string> keys = new Dictionary<string, string>();
            try
            {
                for(int i = 0; i < dataRows.Length; i++)
                {
                    
                    string cOrderNo = dataRows[i]["cOrderNo"].ToString();
                   
                    if(!VaildBomObj.ContainsKey(cOrderNo))
                    {
                        VaildBomObj.Add(cOrderNo, new Dictionary<string, Dictionary<string, Dictionary<string, string>>>());
                    }
                    string cMatNo = dataRows[i]["cMatNo"].ToString();
                    if (!VaildBomObj[cOrderNo].ContainsKey(cMatNo))
                    {
                        VaildBomObj[cOrderNo].Add(cMatNo, new Dictionary<string, Dictionary<string, string>>());
                    }
                    string cMatandResNo = dataRows[i]["cMatandResNo"].ToString();
                    if (!VaildBomObj[cOrderNo][cMatNo].ContainsKey(cMatandResNo))
                    {
                        VaildBomObj[cOrderNo][cMatNo].Add(cMatandResNo, new Dictionary<string, string>());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cOperationNo", dataRows[i]["cOperationNo"].ToString() == null ? "" : dataRows[i]["cOperationNo"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cOperationName", dataRows[i]["cOperationName"].ToString() == null ? "" : dataRows[i]["cOperationName"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cOpSeq", dataRows[i]["cOpSeq"].ToString() == null ? "" : dataRows[i]["cOpSeq"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cMatandResName", dataRows[i]["cMatandResName"].ToString() == null ? "" : dataRows[i]["cMatandResName"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cMatandResType", dataRows[i]["cMatandResType"].ToString() == null ? "" : dataRows[i]["cMatandResType"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("dWidth", dataRows[i]["dWidth"].ToString() == null ? "" : dataRows[i]["dWidth"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("dLength", dataRows[i]["dLength"].ToString() == null ? "" : dataRows[i]["dLength"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cSpecifution", dataRows[i]["cSpecifution"].ToString() == null ? "" : dataRows[i]["cSpecifution"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cUnit", dataRows[i]["cUnit"].ToString() == null ? "" : dataRows[i]["cUnit"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("dReqQty", dataRows[i]["dReqQty"].ToString() == null ? "" : dataRows[i]["dReqQty"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cCapacityLow", dataRows[i]["cCapacityLow"].ToString() == null ? "" : dataRows[i]["cCapacityLow"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cCapacityUp", dataRows[i]["cCapacityUp"].ToString() == null ? "" : dataRows[i]["cCapacityUp"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cCapacity", dataRows[i]["cCapacity"].ToString() == null ? "" : dataRows[i]["cCapacity"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cBomid", dataRows[i]["cBomid"].ToString() == null ? "" : dataRows[i]["cBomid"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cSortSeq", dataRows[i]["cSortSeq"].ToString() == null ? "" : dataRows[i]["cSortSeq"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("dPlanQty", dataRows[i]["dPlanQty"].ToString() == null ? "" : dataRows[i]["dPlanQty"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("dVoltage", dataRows[i]["dVoltage"].ToString() == null ? "" : dataRows[i]["dVoltage"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("Unit", dataRows[i]["Unit"].ToString() == null ? "" : dataRows[i]["Unit"].ToString());
                        VaildBomObj[cOrderNo][cMatNo][cMatandResNo].Add("cCateNo", dataRows[i]["cCateNo"].ToString() == null ? "" : dataRows[i]["cCateNo"].ToString());
                    }
                }
            }catch(Exception e)
            {
                throw e;
            }
            return VaildBomObj;
        }
        #endregion

        /**
    * 流水号后四位生产函数
    * @param {Number} str 前一个流水号数字
    * @param {Array} flag 流水号位数
    */
        public string GenerateID(int serialNum, string flag)
        {
            var pad = flag;
            if (10000 == serialNum) serialNum = 0;
            return pad.Substring(0, pad.Length - serialNum.ToString().Length) + serialNum;
        }

        /**
 * 流水号后2位生产函数
 * @param {Number} str 前一个流水号数字
 * @param {Array} flag 流水号位数
 */
        public int GenerateID2(int serialNum, string flag)
        {
            var pad = flag;
            //if (10000 === str) str = 0;
            //return pad.substring(0, pad.length - str.toString().length) + str;
            return serialNum;
        }

        //json序列化防止追加
        public string ToJsonString(Object obj)
        {
            JsonSerializerSettings jsSettings = new JsonSerializerSettings();
            jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            return JsonConvert.SerializeObject(obj, jsSettings);
        }

        //dataRow转json
        public string dataRowToJson(DataRow dataRow)
        {
            string json = ToJsonString(dataRow);
            json = JosnChange(json);
            Newtonsoft.Json.Linq.JArray jsonArr = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(json);
            string ret = jsonArr[0]["ItemArray"].ToString();
            return ret;
        }

        public bool insertSqlList(List<string> para)
        {
            bool ret = true;
            string sql = "";
            try
            {
                for (int i = 0; i < para.Count; i++)
                {
                    sql += para[i];

                }
                var connstr = SqlHelper.GetConnSting();
                SqlHelper.ExecuteNonQuery(connstr, CommandType.Text, sql);
            }
            catch (Exception)
            {
                ret = false;
            }
            return ret;
        }

        //DataRow[] 转 DataTable
        public DataTable ToDataTable(DataRow[] rows)
        {
            if (rows == null || rows.Length == 0) return null;
            DataTable tmp = rows[0].Table.Clone();  // 复制DataRow的表结构  
            foreach (DataRow row in rows)
                tmp.Rows.Add(row.ItemArray);  // 将DataRow添加到DataTable中  
            return tmp;
        }

        /**
 * 日期加减
 * @param {String} date 日期
 * @param {num} days 天数
 * @param {boolean} isAdd 0时是减天数，1为加天数
 */
        public string addDate(string date, int days, int isAdd)
        {
            DateTime d =  DateTime.Parse(date);
            if (isAdd == 1)
            {
               d = d.AddDays(days);
            }
            else
            {
               d =  d.AddDays(-days);
            }
            return d.ToString("yyyy-MM-dd");
        }

        /**
 * @description 获取各班次上下班时间对应的完整格式，包含日期、时间
 * @param {String} date
 * @param {String} shift1 '08:00-11:45,12:45-20:00'
 * @param {String} shift2 '20:00-01:00,02:00-08:00'
 * @returns {Object}
 */
        public Dictionary<string,string> formatShift(string date,string shift1, string shift2)
        {
            Dictionary<string, string> ret = new Dictionary<string, string>();
            string[] s1 = shift1.Split(',');
            string[] s1_t1 = s1[0].Split('-');
            string[] s1_t2 = s1[1].Split('-');

            string[] s2 = shift2.Split(',');
            string[] s2_t1 = s2[0].Split('-');
            string[] s2_t2 = s2[1].Split('-');

            DateTime s1_st1 = DateTime.Parse(date + " " + s1_t1[0]);//第1个班次 第1个上班时间
            DateTime s1_et1 = DateTime.Parse(date + " " +  s1_t1[1]);//第1个班次 第1个下班时间
            DateTime s1_st2 = DateTime.Parse(date + " " + s1_t2[0]);//第1个班次 第2个上班时间
            DateTime s1_et2 = DateTime.Parse(date + " " + s1_t2[1]);//第1个班次 第2个下班时间

            DateTime s2_st1 = DateTime.Parse(date + " " + s2_t1[0]);//第2个班次 第1个上班时间
            DateTime s2_et1 = DateTime.Parse(date + " " + s2_t1[1]);//第2个班次 第1个下班时间
            DateTime s2_st2 = DateTime.Parse(date + " " + s2_t2[0]);//第2个班次 第2个上班时间
            DateTime s2_et2 = DateTime.Parse(date + " " + s2_t2[1]);//第2个班次 第2个下班时间

            if (s2_st1 < s1_et2)
            {
                s2_st1 = s2_st1.AddDays(1);
            }
            if (s2_et1 < s1_et2)
            {
                s2_et1 = s2_et1.AddDays(1);
            }
            if (s2_st2 < s1_et2)
            {
                s2_st2 = s2_st2.AddDays(1);
            }
            if (s2_et2 < s1_et2)
            {
                s2_et2 =  s2_et2.AddDays(1);
            }

            ret.Add("s1_st1", s1_st1.ToString("yyyy-MM-dd hh:mm:ss"));
            ret.Add("s1_et1", s1_et1.ToString("yyyy-MM-dd hh:mm:ss"));
            ret.Add("s1_st2", s1_st2.ToString("yyyy-MM-dd hh:mm:ss"));
            ret.Add("s1_et2", s1_et2.ToString("yyyy-MM-dd hh:mm:ss"));
            ret.Add("s2_st1", s2_st1.ToString("yyyy-MM-dd hh:mm:ss"));
            ret.Add("s2_et1", s2_et1.ToString("yyyy-MM-dd hh:mm:ss"));
            ret.Add("s2_st2", s2_st2.ToString("yyyy-MM-dd hh:mm:ss"));
            ret.Add("s2_et2", s2_et2.ToString("yyyy-MM-dd hh:mm:ss"));

            return ret;
        }

        /**
 * 求得两个时间相减的小时间隔,且向上取整
 */
        public int  diffHour(string date, string date1)
        {
            long s1 = CommonMethod.Instance.GetIntFromTime(DateTime.Parse(date));
            long s2 = CommonMethod.Instance.GetIntFromTime(DateTime.Parse(date1));
            long days = s1 - s2;
            int time = (int)days / 1000 / 60 / 60;
            return time;
        }

        // 自定义函数AddElement()，用于向数组中添加元素并返回更新后的数组
        public object[] AddElement(object[] originalArray, object newElement)
        {
            List<object> list = new List<object>(originalArray);   // 将原始数组转换为List对象
            list.Add(newElement);                                     // 添加新元素
            return list.ToArray();                                      // 将List对象转换回数组形式并返回
        }

        //判断没批次数是否独立成批
        public bool IndependentBatch(float dPlanDty,float Batch)
        {
            try
            {
                if(dPlanDty < Batch)
                {
                    return true;
                }
                if(dPlanDty == Batch)
                {
                    return true;
                }
                if(dPlanDty > Batch)
                {
                    float remainder = dPlanDty % Batch;
                    float BatchPect = (float)(Batch * 0.2);
                    if(remainder <= BatchPect)
                    {
                        return false;
                    }
                }
            }
            catch (Exception ex)
            {
                return true;//返回true是独立成批
            }
            return true;
        }
    }
}